using System;
using System.Collections;
using System.Diagnostics;
using System.Net.Mail;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.InsightUtilities;
using PHSRAG.Insight21.InsightWebControls;
using PHSRAG.Insight21.Policy;
using PHSRAG.Utility;

namespace PHSRAG.Insight21.Common.DownloadBarHelper
{
    /// <summary>
    /// This page acts as a popup form for entering summary e-mail address and message information.
    /// </summary>
    /// <remarks>
    /// Please note: This page makes a critical assumption that it was opened as a popup, and will close itself
    /// when it completes sending a message. If this page is not opened as a popup, the current page will be closed.
    /// </remarks>
    public partial class EmailHost : BasePage
    {
        #region Constants

        private const string ClientScriptKey = "clientScript_349B469B-8140-45d6-BAB7-BB2D6378206F";

        #endregion

        #region Instance Variables

        private ICachePolicy _cachePolicy;

        #endregion

        #region Event Handlers

        protected void OnPageLoad(object sender, EventArgs e)
        {
            // No page loading processes are required beyond resetting the annunciator;
            // all major event handling happens in OnSend.
            annunciator.Message = "";
            annunciator.Title = "";
        }

        /// <summary>
        /// Send button event handler. It only sends the e-mail if the page passed validations.
        /// </summary>
        /// <remarks>
        /// This button click event will close the current window when it finishes, so if this is not implemented
        /// as a popup it will close whatever window it is in.
        /// 
        /// Session is used here instead of PageCachePolicy due to the InsightDownloadBar's inability
        /// to access the default keys related to interpage information passing in the PageCachePolicy scheme.
        /// </remarks>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Information accompanying the event itself.</param>
        protected void OnSend(object sender, EventArgs e)
        {
            try
            {
                if (IsValid && postbackGuard.IsValid)
                {
                    Hashtable dictionary = Session[InsightDownloadBar.EmailDataKey] as Hashtable;
                    if (dictionary == null)
                    {
                        throw new Exception("Required e-mail information was not available.");
                    }

                    // Cannot use "as int" because int is not a reference type, so check if it's null first.
                    int queryId = -1;
                    object passedQueryId = dictionary[InsightDownloadBar.QueryIdKey];
                    if (passedQueryId != null)
                    {
                        queryId = (int) passedQueryId;
                    }

                    SendEmail(dictionary[InsightDownloadBar.WebConfigURLKey] as string,
                        queryId,
                        dictionary[InsightDownloadBar.SummaryInfoKey] as Hashtable);

                    // Close this popup window once send has completed.
                    if (!Page.ClientScript.IsClientScriptBlockRegistered(ClientScriptKey))
                    {
                        string script = "<script language=\"javascript\">\n" +
                            "window.close();\n" +
                                "</script>";

                        Page.ClientScript.RegisterClientScriptBlock(GetType(), ClientScriptKey, script);
                    }
                }
            }
            catch (Exception ex)
            {
                annunciator.Message = string.Format("The following error occurred when processing your request: {0}<br>Please close this window and try again later.", ex.Message);
                ExceptionReport.WriteToEventLog("DownloadBar SendEmail", ex, true, ExceptionReport.ReportType.Error);
            }
        }

        /// <summary>
        /// Ensures that at least the To address field was provided.
        /// </summary>
        /// <param name="source">The object raising an event.</param>
        /// <param name="args">Information accompanying the event itself.</param>
        private void OnValidate(object source, ServerValidateEventArgs args)
        {
            args.IsValid = toField.Text.Trim() != string.Empty;
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Insight application specific e-mail functionality for use in the DownloadBar WebControl.
        /// Gathers required information to send a summary e-mail about the desired page status as well as a link
        /// to the detail page.
        /// </summary>
        /// <param name="webConfigURLKey">Key in Web.config representing the detail page's URL</param>
        /// <param name="queryId">The querry ID number returned when the calling detail page inserted its query string into the database</param>
        /// <param name="summaryInfo">Additional information about page totals and current fund number</param>
        private void SendEmail(string webConfigURLKey, int queryId, Hashtable summaryInfo)
        {
            if (webConfigURLKey != null && queryId >= 0)
            {
                UserContext userContext = _cachePolicy.GetCachedObject(UserContext.CacheKey) as UserContext;
                Debug.Assert(userContext != null);

                if (toField.Text.Trim() == string.Empty)
                {
                    // This should never be reached because of the validation event
                    throw new Exception("Problem receiving e-mail message To address.");
                }

                string fromEmailAddress = userContext.EmailAddress;
                if (fromEmailAddress == string.Empty)
                {
                    throw new Exception("Your e-mail was not sent.  You must have a valid e-mail address in Insight to be able to send an e-mail.");
                }

                MailMessage message = new MailMessage(fromEmailAddress, toField.Text.Trim());

                // User defined (optional, no default)
                if (ccField.Text.Trim() != string.Empty)
                {
                    message.CC.Add(ccField.Text.Trim());
                }

                // User defined (optional, no default)
                if (bccField.Text.Trim() != string.Empty)
                {
                    message.Bcc.Add(bccField.Text.Trim());
                }

                // If fund number is specified by detail page, subject displays default message
                // about fund status; if there is no fund number specified the more generic subject
                // will be used.
                if (summaryInfo != null && summaryInfo[Email.FundNumberKey] != null)
                {
                    message.Subject = String.Format("{0}{1}",
                        Settings.GetKeyValue("Email.DefaultSubject", ""),
                        summaryInfo[Email.FundNumberKey]);
                }
                else
                {
                    message.Subject = Settings.GetKeyValue("Email.NoFundSubject", "");
                }

                // User defined (optional, no default)
                string optionalUserMessage = userMessageField.Text.Trim();

                if ((message.Body = Email.BuildEmailBody(webConfigURLKey, queryId, summaryInfo, optionalUserMessage)) == null)
                {
                    throw new Exception("Problem formatting e-mail message body.");
                }

                message.IsBodyHtml = true;

                SmtpClient client = new SmtpClient(Settings.GetKeyValue("Email.SMTPServer", "127.0.0.1"));
                client.Send(message);
            }
            else
            {
                throw new Exception("Required e-mail information was not available.");
            }
        }

        #endregion

        #region Web Form Designer generated code

        /// <summary>
        /// Generated Code: Initializes page
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);

            _cachePolicy = (Policy.ICachePolicy) Page.Session[Policy.Names.CachePolicyKey];
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.searchCriteriaValidator.ServerValidate += new System.Web.UI.WebControls.ServerValidateEventHandler(this.OnValidate);
            this.Load += new System.EventHandler(this.OnPageLoad);
        }

        #endregion
    }
}

// --- EOF ---